#import "PathProviderExPlugin.h"
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIDocumentInteractionController.h>

@interface PathProviderExPlugin()<UIDocumentInteractionControllerDelegate>

@property(nonatomic, strong) UIDocumentInteractionController *documentController;

@property(nonatomic, strong) FlutterResult rst;

@end


NSString* GetDirectoryOfType(NSSearchPathDirectory dir) {
  NSArray* paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES);
  return paths.firstObject;
}

static FlutterError* getFlutterError(NSError* error) {
  if (error == nil) return nil;
  return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %ld", (long)error.code]
                             message:error.domain
                             details:error.localizedDescription];
}

@implementation PathProviderExPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"com.jacky/path_provider"
            binaryMessenger:[registrar messenger]];
  PathProviderExPlugin* instance = [[PathProviderExPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([@"getTemporaryDirectory" isEqualToString:call.method]) {
        NSString* s = GetDirectoryOfType(NSCachesDirectory);
        result(s);
    } else if ([@"getDownloadsDirectory" isEqualToString:call.method]) {
        NSString* s = GetDirectoryOfType(NSCachesDirectory);
        result(s);
    } else if ([@"getApplicationDocumentsDirectory" isEqualToString:call.method]) {
          NSString* s = GetDirectoryOfType(NSDocumentDirectory);
            result(s);
      } else if ([@"getApplicationSupportDirectory" isEqualToString:call.method]) {
          NSString* path = GetDirectoryOfType(NSApplicationSupportDirectory);


        // Create the path if it doesn't exist
        NSError* error;
        NSFileManager* fileManager = [NSFileManager defaultManager];
        BOOL success = [fileManager createDirectoryAtPath:path
                              withIntermediateDirectories:YES
                                               attributes:nil
                                                    error:&error];
        if (!success) {
          result(getFlutterError(error));
        } else {
          result(path);
        }
      } else if ([@"getLibraryDirectory" isEqualToString:call.method]) {
          NSString* s = GetDirectoryOfType(NSLibraryDirectory);
            result(s);
      } else if ([@"getVideoDuration" isEqualToString:call.method]) {
          NSString* p = call.arguments[@"path"];
          AVURLAsset * asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:p]];
              CMTime   time = [asset duration];
              int seconds = (int)time.value/time.timescale;
            result([NSNumber numberWithInt:seconds * 1000]);
      } else if ([@"getAvailableSize" isEqualToString:call.method]) {
//        long long s = getFreeDiskSpaceInBytes(); //按很大的值来写，暂时不知道怎么取值
          NSURL *url = [NSURL fileURLWithPath:NSHomeDirectory()];
          NSNumber *capacity = nil;
          [url getResourceValue:&capacity
                          forKey:NSURLVolumeAvailableCapacityForOpportunisticUsageKey
                           error:nil];
        result(capacity);
      } else if ([@"getAvailableStoragePercent" isEqualToString:call.method]) {
            int s = getFreeDiskSpacePercentage(); //不知道怎么取，按永远都有可用空间
              result([NSNumber numberWithInt:s]);
      } else if ([@"installApp" isEqualToString:call.method]) {
            NSString* p = call.arguments;
            NSURL* nsUrl = [NSURL URLWithString:p];
            if (@available(iOS 10.0, *)) {
                [[UIApplication sharedApplication] openURL:nsUrl options:@{} completionHandler:nil];
            } else {
                [[UIApplication sharedApplication] openURL:nsUrl];
            }
        } else if ([@"environmentCheck" isEqualToString:call.method]) {
                int s = 0;
                  result([NSNumber numberWithInt:s]);
        } else if ([@"thumbnailImage" isEqualToString:call.method]){
            NSString *path = [call.arguments valueForKey:@"path"];
            NSString *thumbPath = [call.arguments valueForKey:@"thumbPath"];
            CGFloat width = [[call.arguments valueForKey:@"width"] floatValue];
            CGFloat height = [[call.arguments valueForKey:@"height"] floatValue];
            [self generateThumbnailFromImagePath:path thumbnailPath:thumbPath width:width height:height result:result];
        } else if ([@"exifInfo" isEqualToString:call.method]){
            result([self extractMetadataFromImagePath:call.arguments]);
        } else if ([call.method isEqualToString:@"moveFile"]) {
            NSString *path = call.arguments;
            if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
               self.documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
               self.documentController.delegate = self;
               [self.documentController presentOpenInMenuFromRect:[UIApplication sharedApplication].keyWindow.rootViewController.view.bounds inView:[UIApplication sharedApplication].keyWindow.rootViewController.view animated:YES];
                self.rst = result;
//               result(@(YES));
            }else{
               result(@(NO));
            }
        } else {

        result(FlutterMethodNotImplemented);
      }
}


/// 获取剩余磁盘空间（单位 byte）
int64_t getFreeDiskSpaceInBytes() {
    NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
    NSNumber *freeSize = attributes[NSFileSystemFreeSize];
    return freeSize.longLongValue;
}

/// 获取剩余磁盘空间百分比（0~100）
int getFreeDiskSpacePercentage() {
    NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
    NSNumber *freeSize = attributes[NSFileSystemFreeSize];
    NSNumber *totalSize = attributes[NSFileSystemSize];
    
    if (totalSize.longLongValue == 0) {
        return 0;
    }
    
    double percent = (double)freeSize.longLongValue / totalSize.longLongValue * 100.0;
    return (int)round(percent);
}



- (void)generateThumbnailFromImagePath:(NSString *)sourcePath
                      thumbnailPath:(NSString *)thumbnailPath
                               width:(CGFloat)width
                              height:(CGFloat)height
                                result:(FlutterResult)result {

    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(backgroundQueue, ^{
        BOOL success = NO;
        // 加载原图
        UIImage *sourceImage = [UIImage imageWithContentsOfFile:sourcePath];

        if (!sourceImage) {
            NSLog(@"无法加载图片: %@", sourcePath);
            success = NO;
        }

        // 创建缩放后的尺寸
        CGSize targetSize = CGSizeMake(width, height);

        // 开始图形上下文
        UIGraphicsBeginImageContext(targetSize);

        // 绘制图像到指定大小
        [sourceImage drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];

        // 从上下文获取新的缩略图图像
        UIImage *thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();

        // 结束图形上下文
        UIGraphicsEndImageContext();

        // 获取缩略图图像的二进制数据
        NSData *thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 0.2);

        // 将缩略图保存到文件
        if ([thumbnailData writeToFile:thumbnailPath atomically:YES]) {
            NSLog(@"缩略图保存成功: %@", thumbnailPath);
            success = YES;
        } else {
            NSLog(@"缩略图保存失败: %@", thumbnailPath);
            success = NO;
        }
        // 在主线程中执行更新UI等操作
        dispatch_async(dispatch_get_main_queue(), ^{
            result(@(NO));
        });
    });


}

- (NSDictionary *)extractMetadataFromImagePath:(NSString *)imagePath {
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    [dic setValue:@"" forKey:@"time"];
    [dic setValue:@(0) forKey:@"width"];
    [dic setValue:@(0) forKey:@"height"];
    [dic setValue:@(0) forKey:@"latitude"];
    [dic setValue:@(0) forKey:@"longitude"];
    // 加载图片
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

    /// 无法加载图片
    if (!image) {
        NSLog(@"无法加载图片: %@", imagePath);
        return dic;
    }

    // 获取图片的宽高
    CGSize imageSize = image.size;
    [dic setValue:@(image.size.width) forKey:@"width"];
    [dic setValue:@(image.size.height )forKey:@"height"];
    NSLog(@"图片宽度: %f, 高度: %f", imageSize.width, imageSize.height);

    // 获取图片的元数据
    NSURL *imageURL = [NSURL fileURLWithPath:imagePath];
    CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)imageURL, NULL);

    /// 无法创建图片源
    if (!source) {
        NSLog(@"无法创建图片源");
        return dic;
    }

    NSDictionary *metadata = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
    CFRelease(source);

    /// 无法获取图片元数据
    if (!metadata) {
        NSLog(@"无法获取图片元数据");
        return dic;
    }

    // 获取拍摄时间
    NSString *dateTimeOriginal = metadata[(NSString *)kCGImagePropertyExifDateTimeOriginal];
    NSLog(@"拍摄时间: %@", dateTimeOriginal);
    [dic setValue:dateTimeOriginal forKey:@"time"];

    // 获取经纬度
    NSDictionary *gpsDict = metadata[(NSString *)kCGImagePropertyGPSDictionary];
    if (gpsDict) {
        NSString *latitudeRef = gpsDict[(NSString *)kCGImagePropertyGPSLatitudeRef];
        NSString *longitudeRef = gpsDict[(NSString *)kCGImagePropertyGPSLongitudeRef];
        NSNumber *latitude = gpsDict[(NSString *)kCGImagePropertyGPSLatitude];
        NSNumber *longitude = gpsDict[(NSString *)kCGImagePropertyGPSLongitude];

        if (latitude && longitude) {
            double lat = [latitude doubleValue];
            double lon = [longitude doubleValue];

            if ([latitudeRef isEqualToString:@"S"]) {
                lat = -lat;
            }
            if ([longitudeRef isEqualToString:@"W"]) {
                lon = -lon;
            }
            [dic setValue:@(lat) forKey:@"latitude"];
            [dic setValue:@(lon) forKey:@"longitude"];
            NSLog(@"经度: %f, 纬度: %f", lon, lat);
        } else {
            NSLog(@"没有GPS信息");
        }
    } else {
        NSLog(@"没有GPS信息");
    }
    return dic;
}

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
    return [UIApplication sharedApplication].keyWindow.rootViewController;
}

- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller {
    self.rst(@(YES));
}


@end
